use serde::{Deserialize, Serialize};
use std::fmt;
use crate::loader::ConfigFormat;

/// 远程认证方式
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RemoteAuth {
    Bearer(String),
    Basic { username: String, password: String },
}

/// 配置来源枚举
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ConfigSource {
    /// 文件配置源
    File {
        path: String,
        format: ConfigFormat,
    },
    /// 环境变量配置源
    Environment {
        prefix: String,
    },
    /// 远程配置源
    Remote {
        url: String,
        format: ConfigFormat,
        auth: Option<RemoteAuth>,
    },
    /// 内嵌默认配置
    Embedded {
        config: super::config::RustCloudConfig,
    },
}

impl ConfigSource {
    /// 获取配置的优先级（数值越大优先级越高）
    pub fn priority(&self) -> u32 {
        match self {
            ConfigSource::Embedded { .. } => 0,
            ConfigSource::File { .. } => 1,
            ConfigSource::Environment { .. } => 2,
            ConfigSource::Remote { .. } => 3,
        }
    }

    /// 获取缓存键
    pub fn cache_key(&self) -> String {
        match self {
            ConfigSource::File { path, .. } => format!("file: {}", path),
            ConfigSource::Environment { prefix } => format!("env: {}", prefix),
            ConfigSource::Remote { url, .. } => format!("remote: {}", url),
            ConfigSource::Embedded { .. } => "embedded".to_string(),
        }
    }
}

impl fmt::Display for ConfigSource {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ConfigSource::File { path, format } => write!(f, "File({}: {:?})", path, format),
            ConfigSource::Environment { prefix } => write!(f, "Environment({})", prefix),
            ConfigSource::Remote { url, format, .. } => write!(f, "Remote({}: {:?})", url, format),
            ConfigSource::Embedded { .. } => write!(f, "Embedded"),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_config_source_priority() {
        let embedded = ConfigSource::Embedded {
            config: super::super::config::RustCloudConfig::default(),
        };
        let file = ConfigSource::File {
            path: "/tmp/config.yaml".to_string(),
            format: ConfigFormat::Yaml,
        };
        let env = ConfigSource::Environment {
            prefix: "RUSTCLOUD".to_string(),
        };
        let remote = ConfigSource::Remote {
            url: "http://localhost:8080/config".to_string(),
            format: ConfigFormat::Json,
            auth: None,
        };

        assert!(embedded.priority() < file.priority());
        assert!(file.priority() < env.priority());
        assert!(env.priority() < remote.priority());
    }

    #[test]
    fn test_config_source_cache_key() {
        let file = ConfigSource::File {
            path: "/tmp/config.yaml".to_string(),
            format: ConfigFormat::Yaml,
        };
        assert_eq!(file.cache_key(), "file: /tmp/config.yaml");

        let env = ConfigSource::Environment {
            prefix: "RUSTCLOUD".to_string(),
        };
        assert_eq!(env.cache_key(), "env: RUSTCLOUD");
    }
}